#pragma once

#include <memory>
#include <string>
#include <vector>
#include <fstream>
#include <nlohmann/json.hpp>
#include "http_client.h"
#include "serial.h"
#include "socket_client.h"

struct Lock
{
    std::string lock;
    std::string zone;
    std::string lock_numble;
    std::string status;
    std::string brand_code;
    std::string organization;
    std::string controller_id;
    std::string phone;
    std::string person;
    std::string collect_time;
    std::string use_time;
    std::string type;
    std::string layer;
    std::string cabinet_number;
    std::string effective_time;
};

struct DeviceConfig
{
    std::string brand_code;
    std::string organization;
    std::string zone;
    std::string sn_code;
    std::string device_type;
    // 新增四个认证方式
    bool auth_enabled = false;
    bool card_enabled = false;
    bool palm_enabled = false;
    bool face_enabled = false;
};

struct OrgConfig
{
    std::string organization;
    std::string club_id;
    std::string key;
};

struct PersonConfig
{
    std::string person;
    std::string phone;
    std::string type;
    std::string passwd;
};

class BoardUtils
{
public:
    static BoardUtils &getInstance(); // 单例获取

    Lock httpDistributeLock(const std::string &brand_code, const std::string &organization,
                            const std::string &zone, const std::string &phone, const std::string &type, const std::string &layer);

    PersonConfig httpGetPersonConfig(const std::string &brand_code, const std::string &organization,
                                    const std::string &zone, const std::string &phone);

    Lock httpQueryLock(const std::string &brand_code, const std::string &organization,
                       const std::string &zone, const std::string &phone, const std::string &type);

    Lock httpReturnLock(const std::string &brand_code, const std::string &organization,
                        const std::string &zone, const std::string &phone, const std::string &type);

    int httpGetAmountCabinetByLayer(const std::string &brand_code, const std::string &organization,
                                    const std::string &zone, const std::string &layer);

    void httpUploadLog(const std::string &brand_code, const std::string &organization,
                       const std::string &zone, const std::string &phone, const std::string &cabinet_number,
                       const std::string &cabinet_type, const std::string &action);
    
     bool httpGetZoneAuthEnabled(const std::string &brand_code, const std::string &organization, const std::string &zone);                   

    std::vector<Lock> httpGetAllLocks(const std::string &brand_code, const std::string &organization,
                                      const std::string &zone);
    std::string httpGetContractId(const std::string &brand_code, const std::string &club_id,
                                       const std::string &key,
                                       const std::string &phone
                                       );
    OrgConfig httpGetOrgConfig(const std::string &brand_code, const std::string &organization);
    std::string  httpCheckIn(const std::string &brand_code, const std::string &club_id,
                   const std::string &contract_id, const std::string &key,
                   const std::string &phone, const std::string &identity_type,
                   const std::string &device_name);
    void httpGetQrCode(const std::string &brand_code, const std::string &env_version, const std::string &filename);
    DeviceConfig loadDeviceConfig(const std::string &txtfile);

    Serial *serial() const { return serial_.get(); }
    HttpClient *httpClient() const { return http_client_.get(); }
    SocketClient *socketClient() const { return socket_client_.get(); }
    httplib::Client *ankeHttpClient() const { return anke_http_client_.get(); }

private:
    BoardUtils(); // 构造私有
    ~BoardUtils();
    BoardUtils(const BoardUtils &) = delete;
    BoardUtils &operator=(const BoardUtils &) = delete;

    std::unique_ptr<HttpClient> http_client_;
    std::unique_ptr<httplib::Client> anke_http_client_;
    std::unique_ptr<Serial> serial_;
    std::unique_ptr<SocketClient> socket_client_;
};